Overview
A common requirement is to ensure that two tasks do not run at the same time. This is typically because they require exclusive access to a common resource such as a data store in order to ensure that an atomic operation on that resource is completed before another task tries to operate on it.
Exclusion ensures that only a predetermined number of tasks can access a particular resource by maintaining a count of the number that have been granted but not released access and denying granting/denying access based on the count.
How is exclusion implemented in CLIP?
CLIP provides a Counting Semaphore object that provides exclusion capability.
The resource underlying a counting semaphore is a standard operating system semaphore. This object is initialized to a particular value and each time it produces a request event, its internal count is decremented until it reaches zero at which point no more requests can be satisfied. Signaling the semaphore increments the count enabling another request to be satisfied. The semaphore provides two types of event:
- Request-granted (the internal count was non-zero and was decremented)
- Signal-granted (the internal count was incremented)
In the special case where a collector consumes a counting semaphore signal event, the signal is not sent until the collector is closed. This allows a set of method executions to be sequenced by collecting the request from a semaphore that is signaled by a previous method in the chain.
The above diagram shows a processing chain in which every method receives a transient store 'ready-for-read' event but each method can only process it once the previous method in the chain has completed. This allows safe in-place modification of the data in the store.
The following diagram shows the implementation of a mutex. Each collector requests the semaphore and if granted, the corresponding method is fired to perform some processing and when it returns and the event is closed the semaphore is signaled allowing another to request it: